import fs from 'fs-extra';
import fg from 'fast-glob';
import { checkDiskAvailable, gb2byte } from "./tools/vendor.js";
import { Ancestor, IAdditionalMsg, TVersionInfo } from './Ancestor.js';
import { PublishResTask } from './common/tasks/PublishResTask.js';
import { toolchain } from './toolchain.js';
import { SVNOperationTask } from './common/tasks/SVNOperationTask.js';
import { ReadCfgTask } from './common/tasks/ReadCfgTask.js';
import { PrepareI18nTask } from './common/tasks/PrepareI18nTask.js';
import { CompileCSharpTask } from './common/tasks/CompileCSharpTask.js';
import { BuildLock, checkOrLockWorkspace } from './tools/lock.js';
import { WrapCSharpTask } from './common/tasks/WrapCSharpTask.js';
import { CheckEnvTask } from './common/tasks/CheckEnvTask.js';
import { CheckCodeTask } from './common/tasks/CheckCodeTask.js';
import { I18NResult, I18NTask } from './common/tasks/I18NTask.js';
import { CheckFileNameTask } from './common/tasks/CheckFileNameTask.js';
import { DynamicRemoveTask } from './common/tasks/DynamicRemoveTask.js';
import { ValidateTask } from './common/tasks/ValidateTask.js';
import path from 'path';
import { ModifyUnityTextureTask } from './common/tasks/ModifyUnityTextureTask.js';
import { SetScriptDefineTask } from './common/tasks/SetScriptDefineTask.js';
import { SetImportFormatTask } from './common/tasks/SetImportFormatTask.js';
import { saveBuildInfo } from './tools/secretary.js';
import { WebGLDouyinUploadData, WebGLDouyinUploadTask } from './webgl/tasks/WebGLDouyinUploadTask.js';
import { SpecifiedSVNTask } from './common/tasks/SpecifiedSVNTask.js';
import { IMiniGameResult, WebGLPostBuildMiniGameTask } from './webgl/tasks/WebGLPostBuildMiniGameTask.js';

export abstract class Builder extends Ancestor {

    async awake(): Promise<boolean> {
        await this.getParams();
        return true;
    }

    async start(): Promise<void> {
        // 打印参数
        // console.log('构建参数', toolchain.params);
        // 保存构建参数

        // 检查构建锁
        if (fs.existsSync(toolchain.params.workSpacePath)) {
            await checkOrLockWorkspace(BuildLock);
        }

        // 写入构建状态文件，此文件用于指示资源导入时识别是否处于构建抖音环境中
        await this.setBuildStateFile(true);

        // 检查磁盘
        await checkDiskAvailable(toolchain.params.workSpacePath, gb2byte(5));
        
        // 统一添加公共前置任务和后置任务
        this.series.unshift(
            new SVNOperationTask(this.cmdOption),
            new ReadCfgTask(this.cmdOption),
            new SpecifiedSVNTask(this.cmdOption),
            new DynamicRemoveTask(this.cmdOption),
            new SetImportFormatTask(this.cmdOption),
            new SetScriptDefineTask(this.cmdOption),
            new ModifyUnityTextureTask(this.cmdOption),
            new CheckCodeTask(this.cmdOption),
            new CheckFileNameTask(this.cmdOption),
            new ValidateTask(this.cmdOption),
            new CheckEnvTask(this.cmdOption),
            new PrepareI18nTask(this.cmdOption),
            new CompileCSharpTask(this.cmdOption),
            new WrapCSharpTask(this.cmdOption),
        );
        this.series.push(new PublishResTask(this.cmdOption), 
            // new SVNSaveTask(this.cmdOption)
        );

        // 开始执行所有任务
        await this.startSeries();

        // 清除构建状态文件
        await this.setBuildStateFile(false);

        // 保存构建信息到.build/buildInfo.json中
        await saveBuildInfo();
    }

    private async setBuildStateFile(setOrNot: boolean): Promise<void> {
        const bsfRoot = path.join(toolchain.params.workSpacePath, `../.build`);
        const bsfs = await fg('*.building', { cwd: bsfRoot });
        for (const bsf of bsfs) {
            console.log('remove build state file:', bsf);
            await fs.unlink(path.join(bsfRoot, bsf));
        }
        if (setOrNot) {
            let state = toolchain.option.platform;
            if (state == 'WebGL') {
                state += `_${toolchain.option.webglRuntime}`;
            }
            const bsfPath = path.join(bsfRoot, `${state.toLowerCase()}.building`);
            console.log('set build state file:', bsfPath);
            await fs.ensureFile(bsfPath);
        }
    }

    public async getBuildVersionInfo(): Promise<TVersionInfo | null> {
        let version = await toolchain.unity.getFullBuildVer();
        let qrcodeFile: string | undefined = undefined;
        if (this.cmdOption.platform == 'WebGL') {
            if (this.cmdOption.webglRuntime == 'browser') {
                version += '  <font color=\'orange\'>网页版</font>';
            } else if (this.cmdOption.webglRuntime == 'minigame') {
                let wasmSize = '?M';
                const mini = toolchain.taskHelper.getResult<IMiniGameResult>(WebGLPostBuildMiniGameTask.name);
                if (mini?.data) {
                    wasmSize = (mini.data.wasmSize / 1024 / 1024).toFixed(1) + 'M';
                }
                version += `  <font color=\'orange\'>小游戏（wasm: ${wasmSize}）</font>`;
            } else if (this.cmdOption.webglRuntime == 'douyin') {
                version += '  <font color=\'orange\'>抖音</font>';
                const ud = toolchain.taskHelper.getResult<WebGLDouyinUploadData>(WebGLDouyinUploadTask.name);
                if (ud) {
                    qrcodeFile = ud.data?.result.qrcodeFile;
                }
            }
        }
        if (this.cmdOption.buildExe) version += `  <font color='orange'>新包(${toolchain.option.gameIds})</font>`;
        return { version, qrcodeFile };
    }

    public async getAdditionalMessages(): Promise<IAdditionalMsg[]> {
        const msgs: IAdditionalMsg[] = [];

        const i18nRst = toolchain.taskHelper.getResult<I18NResult>(I18NTask.name);
        if (i18nRst != null) {
            const report = i18nRst.data?.out?.report;
            if (report) {
                if (report.jsonSafeErrors.length > 0)
                msgs.push({
                    type: 'text',
                    msg: 'JSON错误将导致无法进入游戏，请优先解决',
                    mention: toolchain.params.channelCfg['localize-responsor']
                });
            }
        }

        // if (toolchain.params.reportLvs.includes('JsonDiff')) {
        //     const svnRst = toolchain.taskHelper.getResult<SVNSumary>(SVNOperationTask.name);
        //     if (svnRst != null && svnRst.data) {
        //         // 上传diff文件到企业微信
        //         let mediaId: string | null = null;
        //         if (svnRst.data.jsonDiff) {
        //             mediaId = await uploadMedia(svnRst.data.jsonDiff);
        //         }
        //         const diffJsonNames = svnRst.data?.diffJsonNames;
        //         if (diffJsonNames?.length) {
        //             let msg = `本次构建更新了${diffJsonNames.length}个配置：${diffJsonNames.join(', ')}`;
        //             if (mediaId) {
        //                 msg += '，具体查看下面的diff文件：';
        //             }
        //             msgs.push({
        //                 type: 'text',
        //                 msg,
        //                 mention: toolchain.startUser
        //             });
        //         }
        //         if (mediaId) {
        //             msgs.push({
        //                 type: 'file',
        //                 file: mediaId
        //             })
        //         }
        //     }
        // }

        return msgs;
    }
}